﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using UnwiseSource.Administration.ToolClasses;
using UnwiseSource.ServiceReference1;

namespace UnwiseSource.Administration
{
    public partial class CourseManagement : System.Web.UI.Page
    {
        FullCourse currentCourse;

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                UserCredibility userCreds = (UserCredibility)Session["userCreds"];
                RedirectBackToLoginIfNotLogged(userCreds);

                Modes mode = DefineMode(); //Defines if we are in edit or create new course MODE

                currentCourse = GetCourse(mode); //creates new course or fetches one from the database
                Session["currentCourse"] = currentCourse;

                Rights userRight = RightsChecker.GetRightsForFullCourse(currentCourse, userCreds);

                GenerateAlias(currentCourse, mode, userRight);

                FillTabs(currentCourse);

                GenerateLists(currentCourse, mode, userRight);

                SyncCourseControls(currentCourse);

                //TODO:
                //GenerateLectures();
            }
        }

        private void RedirectBackToLoginIfNotLogged(UserCredibility userCreds)
        {
            bool redirectBack = true;

            if (userCreds != null)
            {
                if (userCreds.Credible)
                {
                    redirectBack = false;
                }
            }

            if (redirectBack)
            {
                Response.Redirect("~/Administration/Login.aspx");
            }
        }

        private int TakeIdFromQueryString()
        {
            string recievedId = Request.QueryString["cId"];
            int courseId;

            if (int.TryParse(recievedId, out courseId))
            {
                return courseId;
            }

            return -1;
        }

        private Modes DefineMode()
        {
            Modes mode = Modes.New;
            int courseId = TakeIdFromQueryString();

            if (courseId != -1)
            {
                mode = Modes.Edit;
            }

            return mode;
        }

        private FullCourse GetCourse(Modes mode)
        {
            if (mode == Modes.Edit)
            {
                try
                {
                    string accessKey = Helper.getconfigparam("SECID", "");
                    int courseId = TakeIdFromQueryString();

                    Service1Client client = new Service1Client();
                    FullCourse courseFromDB = client.GetFullCourse(accessKey, courseId);

                    return courseFromDB;
                }
                catch (Exception exc)
                {
                    Helper.LogErrorMsg(exc.Message);
                }
            }

            //By some reason they come as nulls from the service - the constructor here doesnt recreate them empty ...
            FullCourse result = new FullCourse();
            result.Names = new List<MultiLingual>();
            result.Summaries = new List<MultiLingual>();
            result.Contributors = new List<ContributorCredentials>();
            return result;
        }

        private void GenerateAlias(FullCourse course, Modes mode, Rights userRight)
        {
            if (mode == Modes.New)
            {
                tb_courseAlias.Visible = Visible;
            }
            else if (mode == Modes.Edit)
            {
                if (userRight == Rights.Owner)
                {
                    tb_courseAlias.Value = course.Alias;
                    tb_courseAlias.Visible = true;
                }
                else
                {
                    p_course_alias.InnerText = course.Alias;
                    p_course_alias.Visible = true;
                }
            }
        }

        private void FillTabs(FullCourse course)
        {
            string courseNameBG = course.Names.FirstOrDefault(cn => cn.Language == "BG").Value;
            tb_courseNameBG.Value = courseNameBG;

            string courseNameEN = course.Names.FirstOrDefault(cn => cn.Language == "EN").Value;
            tb_courseNameEN.Value = courseNameEN;

            string courseSummaryBG = course.Summaries.FirstOrDefault(cs => cs.Language == "BG").Value;
            tb_courseSummaryBG.Value = courseSummaryBG;

            string courseSummaryEN = course.Summaries.FirstOrDefault(cs => cs.Language == "EN").Value;
            tb_courseSummaryEN.Value = courseSummaryEN;
        }

        private void GenerateLists(FullCourse course, Modes mode, Rights userRight)
        {
            if (mode == Modes.New)
            {
                users_list_holder.Visible = true;
                btns_ofLists_holder.Visible = true;
                moderators_list_holder.Visible = true;
                lectors_list_holder.Visible = true;

                AddUserAsLector();

                LoadUsersList();
            }
            else if (mode == Modes.Edit)
            {
                if (userRight == Rights.Owner || userRight == Rights.Admin)
                {
                    users_list_holder.Visible = true;
                    btns_ofLists_holder.Visible = true;
                    moderators_list_holder.Visible = true;
                    lectors_list_holder.Visible = true;

                    //Read situation from course data
                    SyncAllLists(course);

                    //If he wasnt in the list of lectors - the method checks himself if it is already present
                    AddUserAsLector();
                }
                else if (userRight == Rights.Contributor)
                {
                    moderators_list_holder.Visible = true;
                    //Load just the moderator list
                    LoadJustModerators(course);
                }
            }
        }

        private List<UserShort> GetUsersData()
        {
            try
            {
                Service1Client client = new Service1Client();
                string accessKey = Helper.getconfigparam("SECID", "");
                List<UserShort> users = client.GetUsers(accessKey);

                return users;
            }
            catch (Exception exc)
            {
                Helper.LogErrorMsg(exc.Message);
            }

            return null;
        }

        private void LoadUsersList()
        {
            UserCredibility userCreds = (UserCredibility)Session["userCreds"];
            List<UserShort> users = GetUsersData();

            foreach (var user in users)
            {
                if (user.UserId != userCreds.UserId)
                {
                    ListItem item = new ListItem();
                    item.Text = user.Name;
                    item.Value = user.UserId.ToString();

                    list_users.Items.Add(item);
                }
            }
        }

        private void AddUserAsLector()
        {
            UserCredibility userCreds = (UserCredibility)Session["userCreds"];

            ListItem item = new ListItem();
            item.Text = userCreds.Name;
            item.Value = userCreds.UserId.ToString();

            //checks if there isnt the owner as a lector already
            if (cbl_Lectors.Items.FindByText(item.Text) == null)
            {
                cbl_Lectors.Items.Insert(0, item);
            }
        }

        private void SyncCourseControls(FullCourse currentCourse)
        {
            List<Levels> courseLevels = GetCourseLevels();

            foreach (var level in courseLevels)
            {
                ListItem item = new ListItem();
                item.Text = level.LevelName;
                item.Value = level.LevelId.ToString();

                if (level.LevelId == currentCourse.LevelId)
                {
                    item.Selected = true;
                }

                ddl_Levels.Items.Add(item);
            }

            if (currentCourse.StartDate != null)
            {
                //dp_startDate.SelectedDate = currentCourse.StartDate.Value;
            }

            if (currentCourse.EndDate != null)
            {
                //dp_endDate.SelectedDate = currentCourse.EndDate.Value;
            }

            tb_lecturesPerWeek.Text = currentCourse.LecturesPerWeek.ToString();
        }

        private void SyncAllLists(FullCourse course)
        {
            UserCredibility userCreds = (UserCredibility)Session["userCreds"];

            foreach (var contributor in course.Contributors)
            {
                ListItem item = new ListItem();
                item.Text = contributor.Name;
                item.Value = contributor.UserId.ToString();

                if (contributor.UserId != userCreds.UserId)
                {
                    list_moderators.Items.Add(item);
                    list_users.Items.Add(item);
                }

                if (contributor.Lector)
                {
                    item.Selected = true;
                }

                //to keep "your" username at the top of the list
                if (contributor.UserId == userCreds.UserId)
                {
                    cbl_Lectors.Items.Insert(0, item);
                }
                else
                {
                    cbl_Lectors.Items.Add(item);
                }
            }

            //FILL USERS TOO with users that are not in the contributors part
            List<UserShort> users = GetUsersData();
            foreach (var user in users)
            {
                if (list_users.Items.FindByText(user.Name) == null &&
                    user.UserId != userCreds.UserId)
                {
                    ListItem item = new ListItem();
                    item.Text = user.Name;
                    item.Value = user.UserId.ToString();

                    list_users.Items.Add(item);
                }
            }
        }

        private List<Levels> GetCourseLevels()
        {
            try
            {
                Service1Client client = new Service1Client();
                string accessKey = Helper.getconfigparam("SECID", "");
                List<Levels> levels = client.GetCourseLevels(accessKey);

                return levels;
            }
            catch (Exception exc)
            {
                Helper.LogErrorMsg(exc.Message);
            }

            return new List<Levels>();
        }

        private void LoadJustModerators(FullCourse course)
        {
            UserCredibility userCreds = (UserCredibility)Session["userCreds"];
            foreach (var contributor in course.Contributors)
            {
                if (contributor.UserId != userCreds.UserId)
                {
                    ListItem item = new ListItem();
                    item.Text = contributor.Name;
                    item.Value = contributor.UserId.ToString();

                    list_moderators.Items.Add(item);
                }
            }
        }

        protected void btnAdd_Click(object sender, EventArgs e)
        {
            ListItem item = list_users.SelectedItem;
            if (item != null)
            {
                if (!list_moderators.Items.Contains(item))
                {
                    list_moderators.Items.Add(item);
                    item.Selected = false;
                    cbl_Lectors.Items.Add(item);
                }
            }
        }

        protected void btnRemove_Click(object sender, EventArgs e)
        {
            ListItem item = list_moderators.SelectedItem;
            if (item != null)
            {
                list_moderators.Items.Remove(item);
                cbl_Lectors.Items.Remove(item);
            }
        }

        protected void btn_Save_Click(object sender, EventArgs e)
        {
            FullCourse course = (FullCourse)Session["currentCourse"];
            UserCredibility userCreds = (UserCredibility)Session["userCreds"];
            Modes mode = DefineMode();
            Rights right = RightsChecker.GetRightsForFullCourse(course, userCreds);

            CollectAlias(course, mode, right);
            CollectNames(course);
            CollectSummaries(course);
            CollectContributors(course, right);
        }

        private void CollectAlias(FullCourse course, Modes mode, Rights right)
        {
            if (mode == Modes.New || right > Rights.Contributor)
            {
                course.Alias = tb_courseAlias.Value;
            }
            //NO need to take it when it is not a owner scenario or a new course.
        }

        private void CollectNames(FullCourse course)
        {
            //must delete old ones
            course.Names.Clear();

            string bgName = tb_courseNameBG.Value;
            course.Names.Add(new MultiLingual() { Language = "BG", Value = bgName });

            string enName = tb_courseNameEN.Value;
            course.Names.Add(new MultiLingual() { Language = "EN", Value = enName });
        }

        private void CollectSummaries(FullCourse course)
        {
            //must delete old ones
            course.Summaries.Clear();

            string bgSummary = tb_courseSummaryBG.Value;
            course.Summaries.Add(new MultiLingual() { Language = "BG", Value = bgSummary });

            string enSummary = tb_courseSummaryEN.Value;
            course.Summaries.Add(new MultiLingual() { Language = "EN", Value = enSummary });
        }

        private void CollectContributors(FullCourse course, Rights right)
        {
            if (right > Rights.Contributor)
            {
                course.Contributors.Clear();

                //first add the owner as he is not in the moderators list
                UserCredibility userCreds = (UserCredibility)Session["userCreds"];
                ContributorCredentials owner = new ContributorCredentials();

                owner.UserId = userCreds.UserId;
                owner.Name = userCreds.Name;
                owner.Username = userCreds.Username;

                ListItem lItem = cbl_Lectors.Items.FindByText(owner.Name);
                if (lItem.Selected)
                {
                    owner.Lector = true;
                }

                owner.Contribution = "Owner";

                course.Contributors.Add(owner);

                //then add all other contributors
                foreach (ListItem item in list_moderators.Items)
                {
                    ContributorCredentials contributor = new ContributorCredentials();
                    contributor.Name = item.Text;
                    contributor.UserId = Guid.Parse(item.Value);
                    contributor.Contribution = "Contributor";

                    ListItem LectorItem = cbl_Lectors.Items.FindByText(item.Text);
                    if (LectorItem.Selected)
                    {
                        if (item.Selected)
                        {
                            contributor.Lector = true;
                        }
                    }

                    course.Contributors.Add(contributor);
                }
            }

            //If not owner cant change contributors
        }
    }
}